package com.xzzz.irda.guardcat.server.alert;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.xzzz.common.base.pojo.PageRes;
import com.xzzz.common.base.pojo.R;
import com.xzzz.common.base.util.json.JsonUtil;
import com.xzzz.common.base.util.okhttp.HttpUtil;
import com.xzzz.irda.guardcat.core.pojo.Alert;
import com.xzzz.irda.guardcat.server.app.AppManager;
import com.xzzz.irda.guardcat.server.app.pojo.MachineInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 【Server】警告
 *
 * @author xzzz
 */
@Slf4j
@RestController
@RequestMapping("/guardcat/server/alert")
public class AlertController {

    private static final String RESOURCE_NAME_TEST_ALERT = "/guardcat/server/alert/test";

    static {
        initFlowRole();
    }

    private static void initFlowRole() {
        FlowRule rule = new FlowRule();
        rule.setResource(RESOURCE_NAME_TEST_ALERT);
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 快速失败
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);                     // 阈值类型,QPS/线程数
        rule.setCount(1);                                               // 阈值个数,漏桶每秒放行个数
        FlowRuleManager.loadRules(CollUtil.newArrayList(rule));         // 设置规则
    }

    @Autowired
    private AbstractAlertManager alertManager;

    @Autowired
    public AppManager appManager;

    /**
     * 警告列表
     *
     * @param appName   应用名称
     * @param machineId 机器ID
     * @param read      是否已读
     * @return 警告分页
     */
    @GetMapping("/pages")
    public R<?> pages(String appName, String machineId, Boolean read, Integer pageSize, Integer pageNum,
                      @RequestParam(required = false) String id) {
        PageRes<Alert> result = alertManager.pages(appName, machineId, id, read, pageSize, pageNum);
        return R.ok(result);
    }

    /**
     * 机器警告直方图
     *
     * @param appName   应用名称
     * @param machineId 机器ID
     * @return 机器警告直方图
     */
    @GetMapping("/histogram")
    public R<?> histogram(String appName, String machineId) {
        Map<String, Object[]> result = alertManager.histogram(appName, machineId);
        return R.ok(result);
    }

    /**
     * 新增警告规则
     *
     * @param alert 警告信息
     */
    @PostMapping("/add")
    public R<?> add(@RequestBody Alert alert) {
        alertManager.addAndPublish(alert);
        return R.ok(true);
    }

    /**
     * 警告设为已读
     *
     * @param alert 警告信息
     */
    @PostMapping("/read")
    public R<?> read(@RequestBody Alert alert) {
        alertManager.read(alert.getId());
        return R.ok(true);
    }

    /**
     * 机器的未读警告数
     *
     * @param machineId 机器ID
     * @return 警告数
     */
    @GetMapping("/count")
    public R<Long> count(@RequestParam(required = false) String machineId) {
        return R.ok(alertManager.countMachine(machineId, false));
    }


    /**
     * 测试警告
     *
     * @param alert 警告信息
     */
    @PostMapping("/test")
    public R<Boolean> testAlert(@RequestBody Alert alert) {
        MachineInfo machine = appManager.getMachine(alert.getAppName(), alert.getMachineId());
        String url = "http://" + machine.getIp() + ":" + machine.getPort() + machine.getServletContextPath() + "/guardcat/client/alert/send?onlyProd=false";
        Map<String, Object> requestBody = new HashMap<>(3);
        requestBody.put("title", "测试警告标题");
        requestBody.put("content", "测试警告内容");
        requestBody.put("notification", true);
        HttpUtil.post(url, JsonUtil.toJson(requestBody));
        return R.ok(true);
    }

}
